# -*- coding: utf-8 -*-
import mod.server.extraServerApi as serverApi
from mod.server.system.serverSystem import ServerSystem

from dwjjCoreServerScripts.common import consts


class WorldModule(object):
    respawnPos = None
    # 世界保护字典
    # key:worldId  ->  v:setting
    worldProtectDict = dict()

    def __init__(self, serverSystem, config):
        # type: (ServerSystem, dict) -> None
        self.serverSystem = serverSystem
        self.config = config
        # 判断该系统是否启用
        if not config["enable"]:
            self.enable = False
            return

        # 初始化引擎工厂
        self.InitComp()
        # 初始化基础参数
        self.InitSetting()
        # 注册监听器
        self.InitListener()

    def InitComp(self):
        self.blockUseEventWhiteList = serverApi.GetEngineCompFactory().CreateBlockUseEventWhiteList(serverApi.GetLevelId())

    def InitSetting(self):
        self.respawnPos = self.config["respawnPos"]
        # 世界保护相关
        self.worldProtectDict = self.config["worldProtect"]
        for k in self.worldProtectDict["useProtect"]:
            for v in self.worldProtectDict["useProtect"][k]:
                self.blockUseEventWhiteList.AddBlockItemListenForUseEvent(v + ":*")

    def InitListener(self):
        # 来自客户端的配置请求
        self.serverSystem.ListenForEvent(consts.ClientModName, consts.ClientSystemName, consts.WorldModuleConfigRequest, self, self.OnConfigRequest, 0)
        self.serverSystem.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(), "PlayerDieEvent", self, self.OnRespawn, 10)
        # 世界保护模块
        self.serverSystem.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(), "ServerPlayerTryDestroyBlockEvent", self, self.OnPlayerTryDestroyBlock, 0)
        self.serverSystem.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(), "ServerEntityTryPlaceBlockEvent", self, self.OnPlayerTryPlaceBlock, 0)
        self.serverSystem.ListenForEvent(serverApi.GetEngineNamespace(), serverApi.GetEngineSystemName(), "ServerBlockUseEvent", self, self.OnBlockUse, 0)

    # 来自客户端的配置请求
    def OnConfigRequest(self, e):
        responseDict = {
            "worldProtect": self.worldProtectDict
        }
        self.serverSystem.NotifyToClient(e["playerId"], consts.WorldModuleConfigResponse, responseDict)

    def OnRespawn(self, e):
        playerComp = serverApi.GetEngineCompFactory().CreatePlayer(e["id"])
        playerComp.SetPlayerRespawnPos((self.respawnPos[1], self.respawnPos[2], self.respawnPos[3]), self.respawnPos[0])

    # ------ 世界保护部分 ------
    def OnPlayerTryDestroyBlock(self, e):
        if e["dimensionId"] in self.worldProtectDict["breakProtect"]:
            e["cancel"] = True

    def OnPlayerTryPlaceBlock(self, e):
        entityComp = serverApi.GetEngineCompFactory().CreateEngineType(e["entityId"])
        entityType = entityComp.GetEngineType()
        if entityType == serverApi.GetMinecraftEnum().EntityType.Player:
            if e["dimensionId"] in self.worldProtectDict["placeProtect"]:
                e["cancel"] = True

    def OnBlockUse(self, e):
        dim = str(e["dimensionId"])
        if dim in self.worldProtectDict["useProtect"]:
            blockName = e["blockName"]
            if blockName in self.worldProtectDict["useProtect"][dim]:
                e["cancel"] = True
